#include "stdafx.h"
#include "MainForm.h"

#include "ylAboutBox.h"
#include "ylConnectionForm.h"

using namespace yoctolog_viewer;

void MainForm::aboutToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e)
{
	AboutBox ^pAboutBox = gcnew AboutBox();
	pAboutBox->ShowDialog(this);
	delete pAboutBox;
}


System::Void MainForm::openToolStripMenuItem_Click( System::Object^ sender, System::EventArgs^ e )
{
	OpenFileDialog ^pOpenFileDialog = gcnew OpenFileDialog();
	pOpenFileDialog->Filter = "yoctolog session|*.yls";
	pOpenFileDialog->Title = "Open a session";

	System::Windows::Forms::DialogResult res = pOpenFileDialog->ShowDialog();

	if( res == System::Windows::Forms::DialogResult::OK && pOpenFileDialog->FileName != "" )
	{
		SessionControl ^pSessionControl = gcnew SessionControl();

		System::String ^strTabTitle = System::IO::Path::GetFileNameWithoutExtension(pOpenFileDialog->FileName);
		TabPage ^pTabPage = gcnew TabPage(strTabTitle);
		sessionTabControl->TabPages->Add(pTabPage);
		pTabPage->Controls->Add(pSessionControl);
		pTabPage->Tag = pSessionControl;
		pSessionControl->Dock = DockStyle::Fill;

		pSessionControl->OpenSession(pOpenFileDialog->FileName);
	}
}


System::Void MainForm::saveToolStripMenuItem_Click( System::Object^ sender, System::EventArgs^ e )
{
	if( sessionTabControl->SelectedTab )
	{
		SessionControl ^pSessionControl = (SessionControl ^)sessionTabControl->SelectedTab->Tag;
		
		SaveFileDialog ^pSaveFileDialog = gcnew SaveFileDialog();
		pSaveFileDialog->Filter = "yoctolog session|*.yls";
		pSaveFileDialog->Title = "Save the session";
		DateTime ^pStartedSessionTime = pSessionControl->GetSessionData()->StartedDateTime;
		pSaveFileDialog->FileName = pSessionControl->GetSessionData()->ComputerName + "." + pStartedSessionTime->ToString("HH_mm.dd_MM_yyyy") + ".yls";

		System::Windows::Forms::DialogResult res = pSaveFileDialog->ShowDialog();

		if( res == System::Windows::Forms::DialogResult::OK && pSaveFileDialog->FileName != "" )
		{
			pSessionControl->SaveSession(pSaveFileDialog->FileName);
		}
	}
}


void MainForm::StartListening()
{
	m_pNetListenerThread = (gcnew System::ComponentModel::BackgroundWorker());
	m_pNetListenerThread->DoWork += gcnew System::ComponentModel::DoWorkEventHandler(this, &MainForm::netListenerThread_DoWork);

	// Set the TcpListener on port 1337
	Int32 port = 1337;
	System::Net::IPAddress^ localAddr = System::Net::IPAddress::Parse( "127.0.0.1" );

	// TcpListener* server = new TcpListener(port);
	m_pTCPListener = gcnew System::Net::Sockets::TcpListener( localAddr,port );

	// Start listening for client requests.
	m_pTCPListener->Start();

	m_pNetListenerThread->RunWorkerAsync();
}


void MainForm::CreateSessionForClient( System::Net::Sockets::TcpClient ^pClient )
{
	SessionControl ^pSessionControl = gcnew SessionControl();
	pSessionControl->GetSessionData()->StartedDateTime = DateTime::Now;
	pSessionControl->GetSessionData()->RemoteAddress = pClient->Client->RemoteEndPoint->ToString();

	array<Object^> ^ vecArgs = gcnew array<Object^>(1);
	vecArgs[0] = pSessionControl;
	this->Invoke( this->pAddSessionControlDelegate, vecArgs );

	pSessionControl->AcceptClient(pClient);
}


System::Void MainForm::connectToolStripMenuItem_Click( System::Object^ sender, System::EventArgs^ e )
{
	ConnectionForm ^pConnectionForm = gcnew ConnectionForm();
	pConnectionForm->ShowDialog(this);
	delete pConnectionForm;
}


void MainForm::AddSessionControl( SessionControl ^pSessionControl )
{
	TabPage ^pTabPage = gcnew TabPage("New connection");
	sessionTabControl->TabPages->Add(pTabPage);
	pTabPage->Controls->Add(pSessionControl);
	pTabPage->Tag = pSessionControl;
	pSessionControl->Dock = DockStyle::Fill;
	sessionTabControl->SelectedTab = pTabPage;
}


System::Void MainForm::netListenerThread_DoWork( System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e )
{
	while( 1 )
	{
		//blocks until a client has connected to the server
		System::Net::Sockets::TcpClient ^pClient = m_pTCPListener->AcceptTcpClient();

		//create a thread to handle communication 
		//with connected client
		CreateSessionForClient(pClient);
	}
}


void MainForm::AttemptConnection( System::String ^strRemoteAddress )
{
	using namespace System::Net::Sockets;

	// Attempt to connect to any sockets running on our port
	TcpClient ^pClient = gcnew TcpClient();
	Int32 port = 1338;
	System::Net::IPAddress^ localAddr = System::Net::IPAddress::Parse( strRemoteAddress );

	try
	{
		pClient->Connect(localAddr, port);
	} catch( SocketException ^e )
	{
		// We couldn't connect - do nothing
		Console::WriteLine("Could not connect to localhost on port 1338: " + e->ToString());
	}
}


System::Void MainForm::MainForm_Load( System::Object^ sender, System::EventArgs^ e )
{
	pAddSessionControlDelegate = gcnew AddSessionControlDelegate(this, &MainForm::AddSessionControl);

	StartListening();

	// Check if there is a listening application on localhost
	AttemptConnection("127.0.0.1");
}


MainForm::~MainForm()
{
	if (components)
	{
		delete components;
	}

	if( m_pNetListenerThread )
	{
		delete m_pNetListenerThread;
	}
}
